package com.coocaa.framework.ui.view;

import android.content.Context;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.KeyEvent;
import android.view.View;
import android.view.animation.AnimationSet;
import android.view.animation.AnimationUtils;
import android.view.animation.LayoutAnimationController;
import android.widget.AbsListView;
import android.widget.GridView;

import com.coocaa.launcher.wallpaper.AnimatorUtils;
import com.coocaa.x.framework.utils.LogUtils;

import java.lang.reflect.Field;
import java.lang.reflect.Method;

/**
 * Created by luwei on 15-8-28.
 */
public class ScrollGridView extends GridView implements AbsListView.OnScrollListener{
    private static final int SCROLL_DURING = 300;
    private OnItemSelectedListener selectedListener = null;
    private Context context = null;
    private int verticalSpacing = 0;
    private int bottomY = 0;
    private int key = KeyEvent.KEYCODE_DPAD_DOWN;
    private boolean focusChangeLayout = true;
    public ScrollGridView(Context context) {
        super(context);
        init(context);
    }

    public ScrollGridView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context);
    }

    public ScrollGridView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init(context);
    }

    @Override
    public void setVerticalSpacing(int verticalSpacing) {
        this.verticalSpacing = verticalSpacing;
        super.setVerticalSpacing(verticalSpacing);
    }

    private void init(Context context){
        this.context = context;
        setOnScrollListener(this);
    }

    @Override
    public boolean dispatchKeyEvent(KeyEvent event) {
        if (bottomY == 0){
            int[] pos =  new int[2];
            getLocationOnScreen(pos);
            bottomY = pos[1] + getHeight();
            LogUtils.d("pos", "bottonY " + bottomY);
        }
        if (event.getAction() == KeyEvent.ACTION_DOWN) {
            switch (event.getKeyCode()) {
                case KeyEvent.KEYCODE_DPAD_DOWN:
                    int nextY = getNextItemY();
                    if (nextY > bottomY || nextY == 0) {
                        key = event.getKeyCode();
                        smoothScrollBy(getChildAt(0).getHeight() + verticalSpacing, SCROLL_DURING);
                        return true;
                    }
                    break;
                case KeyEvent.KEYCODE_DPAD_UP:
                    int preY = getPreItemY();
                    if (preY < getY() || preY == 0){
                        key = event.getKeyCode();
                        smoothScrollBy(-getChildAt(0).getHeight() - verticalSpacing,SCROLL_DURING);
                        return true;
                    }
                    break;
            }
        }
        return super.dispatchKeyEvent(event);
    }

    private void setDownSelection(){
        int currentPos = getSelectedItemPosition();
        if (isLastCol())
            return;
        if (currentPos + getNumColumns() < getAdapter().getCount())
            setSelection(currentPos + getNumColumns());
        else
            setSelection(getAdapter().getCount() - 1);
    }

    private boolean isLastCol(){
        int current = getCol(getSelectedItemPosition() + 1);
        int total = getCol(getAdapter().getCount());
        if (current == total)
            return true;
        return false;
    }

    private int getCol(int pos){
        int temp = pos / getNumColumns();
        int mode = pos % getNumColumns();
        if (mode != 0){
            temp++;
        }
        return temp;
    }

    private void setUpSelection(){
        int currentPos = getSelectedItemPosition();
        if (currentPos - getNumColumns() >= 0)
            setSelection(currentPos - getNumColumns());
    }



    private int getNextItemY(){
        View view = getSelectedView();
        int currentPos = getSelectedItemPosition();
        if (view != null && currentPos + (currentPos + 1) % getNumColumns() < getAdapter().getCount()){
            int[] pos =  new int[2];
            view.getLocationOnScreen(pos);
            return pos[1] + 2 * view.getHeight();
        }
        return 0;
    }

    private int getPreItemY(){
        View view = getSelectedView();
        int currentPos = getSelectedItemPosition();
        if (view != null && currentPos - getNumColumns() >= 0){
            int[] pos =  new int[2];
            view.getLocationOnScreen(pos);
            return pos[1] - view.getHeight();
        }
        return 0;
    }

    public void setThumbV(int id) {
        try {
            Field mScrollCacheField = View.class.getDeclaredField("mScrollCache");
            mScrollCacheField.setAccessible(true);
            Object mScrollCache = mScrollCacheField.get(this); // scr is your Scroll View

            Field scrollBarField = mScrollCache.getClass().getDeclaredField("scrollBar");
            scrollBarField.setAccessible(true);
            Object scrollBar = scrollBarField.get(mScrollCache);

            Method method = scrollBar.getClass().getDeclaredMethod("setVerticalThumbDrawable", Drawable.class);
            method.setAccessible(true);
            // Set your drawable here.
            method.invoke(scrollBar, getResources().getDrawable(id));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    public boolean setFocus(int pos) {
        if (getAdapter().getCount() > pos) {
            setSelection(pos);
            return true;
        }
        return false;
    }

    public void setAnimation(int id) {
        AnimationSet set = new AnimationSet(true);
        set.addAnimation(AnimationUtils.loadAnimation(context, id));
        LayoutAnimationController controller = new LayoutAnimationController(set, 0.5f);
        controller.setOrder(LayoutAnimationController.ORDER_NORMAL);
        setLayoutAnimation(controller);
    }

    @Override
    public void onScrollStateChanged(AbsListView view, int scrollState) {
        if (scrollState == SCROLL_STATE_IDLE){
            switch (key){
                case KeyEvent.KEYCODE_DPAD_UP:
                    setUpSelection();
                    break;
                case KeyEvent.KEYCODE_DPAD_DOWN:
                    setDownSelection();
                    break;
            }
        }
    }

    @Override
    public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {

    }

    public void showColumn(int col, boolean show) {
        int temp = col;
        while (getChildAt(temp) != null){
            if (show) {
                AnimatorUtils.alpha(getChildAt(temp), 0, 1);
            } else {
                AnimatorUtils.alpha(getChildAt(temp), 1, 0);
            }
            temp = temp + getNumColumns();
        }
    }

    public void fullScroll(int direction){
        try {
            Method method = getClass().getSuperclass().getDeclaredMethod("fullScroll",int.class);
            method.setAccessible(true);
            method.invoke(this,direction);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void setSelection(int position) {
        super.setSelection(position);
        getOnItemSelectedListener().onItemSelected(this,getSelectedView(),position,position);
    }

    @Override
    protected void onFocusChanged(boolean gainFocus, int direction, Rect previouslyFocusedRect) {
        if (focusChangeLayout)
            super.onFocusChanged(gainFocus, direction, previouslyFocusedRect);
    }

    public void setFocusChangeLayout(boolean layout){
        this.focusChangeLayout = layout;
    }
}
